#include "fileserver.h"
#include "filesocket.h"

#include <QTcpSocket>
#include <QHostAddress>

FileServer::FileServer(QString param_server_name,quint8 param_thread_count,QObject *parent) :
    QTcpServer(parent),
    m_server_name(param_server_name),
    m_thread_count(param_thread_count)
{
    //根据用户给定的线程个数进行线程信息数组的申请，并进行初始化
    this->m_socket_thread=new ThreadInfo[this->m_thread_count];
    for(qint32 index=0;index<this->m_thread_count;index++)
    {
        this->m_socket_thread[index].id=index;
        this->m_socket_thread[index].active_count=0;
        //启动线程
        this->m_socket_thread[index].msg_thread.start();
    }

}

FileServer::~FileServer()
{
    if(this->isListening())
    {
        this->close();
    }

    //释放申请的线程信息数组
    delete [] this->m_socket_thread;
    this->m_socket_thread=nullptr;
}

//获取当前每个线程的活跃socket数量
void FileServer::threadMonitor(QMap<qint32, quint32>& param_info)
{
    for(qint32 index=0;index<this->m_thread_count;index++)
    {
        param_info[index]=this->m_socket_thread[index].active_count;
    }
}

//槽函数，服务器监听端口
bool FileServer::run(quint16 port)
{
    if(this->isListening())
    {
        qDebug()<<"port("<<port<<")already listen,please close first."<<endl;
        return true;
    }

    if(this->listen(QHostAddress::Any,port))
    {
        qDebug()<<"listen "<<this->m_server_name<<"port("<<port<<") successful."<<endl;
        return true;
    }
    else
    {
        qDebug()<<"listen "<<"port("<<port<<") failed,please check the network port."<<endl;
        return false;
    }
}

//槽函数
void FileServer::socketClose(qint32 id)
{
    //槽函数，socket关闭的时候，将对应的线程的活跃socket数量减一
    this->m_socket_thread[id].active_count--;
}

//有新连接到来
void FileServer::incomingConnection(qintptr socketDescriptor)
{
    qDebug()<<"new client connection:"<<socketDescriptor<<endl;
    qint32 thread_id=this->getMinActiveThread();
    //建立新的socket
    FileSocket* new_socket=new FileSocket(this->m_socket_thread[thread_id].id,socketDescriptor);
    //绑定套接字关闭信号
    connect(new_socket,SIGNAL(socketClose(qint32)),this,SLOT(socketClose(qint32)));
    //移入到线程中运行
    new_socket->moveToThread(&(this->m_socket_thread[thread_id].msg_thread));
    this->m_socket_thread[thread_id].active_count++;
}

//获取活跃socket数量最少的线程
qint32 FileServer::getMinActiveThread()
{
    qint32 min_id=0;
    for(qint32 index=1;index<this->m_thread_count;index++)
    {
        if(this->m_socket_thread[min_id].active_count>this->m_socket_thread[index].active_count)
        {
            min_id=index;
        }
    }

    return min_id;
}





